package com.github.mrs.test;

import com.github.mrs.spring.BeanPostProcess;
import com.github.mrs.spring.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

/**
 * date: 2023/9/20 14:44
 * author: MR.孙
 */
@Component
public class MrsBeanPostProcess implements BeanPostProcess {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // if (beanName.equals("userService")) {
            // System.out.println(bean);
            // System.out.println("初始化之前...");
        // }
        // return bean;
        Field[] fields = bean.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(MrsValue.class)) {
                field.setAccessible(true);
                try {
                    field.set(bean, field.getAnnotation(MrsValue.class).value());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return bean;

    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        //AOP就是基于这个方法实现的，可以看到传入一个bean，返回一个bean，中间可以做代理操作返回一个代理对象
        if (beanName.equals("userService")) {
            // System.out.println(bean);
            // System.out.println("初始化之后...");

            //代理对象，通过JDK的Proxy.newProxyInstance()；基于反射实现aop。
            // 第一个参数类加载器，第二个参数接口的class对象，第三个参数重写invoke()的InvocationHandler实现类
            Object proxyInstance = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), (proxy, method, args) -> {

                System.out.println("执行切面逻辑--->前置增强");
                //执行的原始对象的方法而不是代理对象
                Object o = method.invoke(bean);
                System.out.println("执行切面逻辑--->后置增强");
                return o;
            });

            return proxyInstance;
        }
        return bean;
    }

}
